﻿using System;
using System.Collections.Generic;
using imaginecup.information;
using imaginecup.objectManager;
using imaginecup.util;
using Imaginecup.componentSystem.component;
using Imaginecup.factory;
using Imaginecup.gameState.malaria.component.children;
using Imaginecup.gameState.malaria.component.entity.fieldItem;
using Imaginecup.gameState.malaria.component.entity.item;
using Imaginecup.gameState.malaria.component.fieldScene;
using Imaginecup.gameState.malaria.component.item;
using Imaginecup.gameState.malaria.component.malaria;
using Imaginecup.gameState.malaria.component.panel.clickAble;
using Imaginecup.gameState.malaria.componentInit;
using Imaginecup.sprite;
using Imaginecup.sprite.changeSourceSize;
using Imaginecup.sprite.factory;
using Imaginecup.gameState.malaria.component.entity.panel;
using Imaginecup.gameState.malaria.component.entity;

namespace Imaginecup.gameState.malaria.component.factory
{
    public enum ItemID { ITEM_ID_PILL, ITEM_SHIELD, ATTACK_HAND, ATTACK_SLICE, ITEM_ID_FLYPAPER, ATTACK_MOVE, ITEM_ID_FROG, ERROR, ITEM_WEB }
    public enum MALARIA_COMPONENT_ID
    {
        ATTACK_MOVE_PANEL, ATTACK_HAND_PANEL, ATTACK_SLICE_PANEL, ITEM_ID_SHIELD_PANEL, ITEM_ID_PILL_PANEL, ITEM_ID_FLYPAPER_PANEL,
        ITEM_ID_FROG_PANEL, CHAR, MALARIA, FIELD_SCENE, ERROR, FIELD_FROG, FIELD_FLYPAPER, HERO,
        HOME,
        ITEM_ID_WEB_PANEL
    }

    class ObjectTypeInfo
    {
        public String TextureName;
        public Object extraInfo;
    }


    public class ObjectFactory : IFactory
    {
        private IFactory m_SpriteFactory;
        private ObjectManager m_ObjMan;

        private ObjectFactory()
        {
            m_SpriteFactory = new SpriteFactory();
        }

        private static ObjectFactory m_ObjectFactroy = null;


        public static ObjectFactory GetObjectFactory()
        {
            if (m_ObjectFactroy == null)
            {
                m_ObjectFactroy = new ObjectFactory();
            }
            return m_ObjectFactroy;
        }

        public static MALARIA_COMPONENT_ID GetObjectID(String type)
        {
            switch (type)
            {
                case "ATTACK_MOVE_PANEL":
                    return MALARIA_COMPONENT_ID.ATTACK_MOVE_PANEL;
                case "ATTACK_HAND_PANEL":
                    return MALARIA_COMPONENT_ID.ATTACK_HAND_PANEL;
                case "ATTACK_SLICE_PANEL":
                    return MALARIA_COMPONENT_ID.ATTACK_SLICE_PANEL;
                case "ITEM_ID_SHIELD_PANEL":
                    return MALARIA_COMPONENT_ID.ITEM_ID_SHIELD_PANEL;
                case "ITEM_ID_PILL_PANEL":
                    return MALARIA_COMPONENT_ID.ITEM_ID_PILL_PANEL;
                case "ITEM_ID_FLYPAPER_PANEL":
                    return MALARIA_COMPONENT_ID.ITEM_ID_FLYPAPER_PANEL;
                case "ITEM_ID_FROG_PANEL":
                    return MALARIA_COMPONENT_ID.ITEM_ID_FROG_PANEL;
            }
            return MALARIA_COMPONENT_ID.ERROR;
        }

        public void SetObjectMan(ObjectManager objMan)
        {
            m_ObjMan = objMan;
        }

        public Object GetObject(Object info)
        {
            MALARIA_COMPONENT_ID typeID = (MALARIA_COMPONENT_ID)info;

            ObjectTypeInfo objTypeID = new ObjectTypeInfo();
            ICmpEntity entity;

            switch (typeID)
            {
                case MALARIA_COMPONENT_ID.FIELD_FROG:
                    objTypeID.extraInfo = ItemID.ITEM_ID_FROG;
                    objTypeID.TextureName = "frog";
                    entity = GetFieldItem(objTypeID);
                    return entity;

                case MALARIA_COMPONENT_ID.FIELD_FLYPAPER:
                    objTypeID.extraInfo = ItemID.ITEM_ID_FLYPAPER;
                    objTypeID.TextureName = "Zzin";
                    entity = GetFieldItem(objTypeID);
                    return entity;

                case MALARIA_COMPONENT_ID.HERO:
                    return GetHero();

                case MALARIA_COMPONENT_ID.HOME:
                    return GetHome();

                case MALARIA_COMPONENT_ID.CHAR:
                    return GetChildren();

                case MALARIA_COMPONENT_ID.MALARIA:
                   return GetMalaria();


                case MALARIA_COMPONENT_ID.ATTACK_MOVE_PANEL:
                    objTypeID.TextureName = PanelImageMan.GetPanelImageName(ItemID.ATTACK_MOVE);
                    objTypeID.extraInfo = ItemID.ATTACK_MOVE;
                    entity = GetCoolTimePanel(objTypeID);

                    return entity;

                case MALARIA_COMPONENT_ID.ATTACK_HAND_PANEL:
                    objTypeID.TextureName = PanelImageMan.GetPanelImageName(ItemID.ATTACK_HAND); // 추후 변경...쉴드 버튼으로.
                    objTypeID.extraInfo = ItemID.ATTACK_HAND;
                    entity = GetCoolTimePanel(objTypeID);
                    return entity;

                case MALARIA_COMPONENT_ID.ATTACK_SLICE_PANEL:
                    objTypeID.TextureName = PanelImageMan.GetPanelImageName(ItemID.ATTACK_SLICE); // 추후 변경...쉴드 버튼으로.
                    objTypeID.extraInfo = ItemID.ATTACK_SLICE;
                    entity = GetCoolTimePanel(objTypeID);

                    return entity;

                case MALARIA_COMPONENT_ID.ITEM_ID_SHIELD_PANEL:
                    objTypeID.TextureName = PanelImageMan.GetPanelImageName(ItemID.ITEM_SHIELD); // 추후 변경...쉴드 버튼으로.
                    objTypeID.extraInfo = ItemID.ITEM_SHIELD;
                    entity = GetClickAbleEntity(objTypeID);
                    return entity;

                case MALARIA_COMPONENT_ID.ITEM_ID_PILL_PANEL:
                    objTypeID.TextureName = PanelImageMan.GetPanelImageName(ItemID.ITEM_ID_PILL); // 추후 변경...쉴드 버튼으로.
                    objTypeID.extraInfo = ItemID.ITEM_ID_PILL;
                    entity = GetClickAbleEntity(objTypeID);
                    return entity;

                case MALARIA_COMPONENT_ID.ITEM_ID_FLYPAPER_PANEL:
                    objTypeID.TextureName = PanelImageMan.GetPanelImageName(ItemID.ITEM_ID_FLYPAPER); // 추후 변경...쉴드 버튼으로.
                    objTypeID.extraInfo = ItemID.ITEM_ID_FLYPAPER;
                    entity = GetClickAbleEntity(objTypeID);
                    return entity;

                case MALARIA_COMPONENT_ID.ITEM_ID_FROG_PANEL:
                    objTypeID.TextureName = PanelImageMan.GetPanelImageName(ItemID.ITEM_ID_FROG); // 추후 변경...쉴드 버튼으로.
                    objTypeID.extraInfo = ItemID.ITEM_ID_FROG;
                    entity = GetClickAbleEntity(objTypeID);
                    return entity;

                case MALARIA_COMPONENT_ID.ITEM_ID_WEB_PANEL:
                    objTypeID.TextureName = PanelImageMan.GetPanelImageName(ItemID.ITEM_WEB); // 추후 변경...쉴드 버튼으로.
                    objTypeID.extraInfo = ItemID.ITEM_WEB;
                    entity = GetClickAbleEntity(objTypeID);
                    return entity;


                case MALARIA_COMPONENT_ID.FIELD_SCENE:
                    entity = GetScene();
                    return entity;
            }

            return null;
        }

        private object GetHome()
        {
            GObjectID id = new GObjectID();
            CmpHome hero = new CmpHome(id, m_ObjMan);
            m_ObjMan.AddComponent(hero);
            return hero;
        }

        private ICmpEntity GetHero()
        {
            GObjectID id = new GObjectID();
            CmpHero hero = new CmpHero(id, m_ObjMan);
            m_ObjMan.AddComponent(hero);
            return hero;
        }

        private ICmpEntity GetFieldItem(ObjectTypeInfo typeInfo)
        {
            ItemID fieldItemID = (ItemID)typeInfo.extraInfo;
            ICmpEntity fieldEntity = null;
            ICmpRender render = null;
            GObjectID id = new GObjectID();

            if (ItemID.ITEM_ID_FLYPAPER == fieldItemID)
            {
                fieldEntity = new CmpFieldFlyPaper(id, m_ObjMan);
                render = new CmpDefaultRender(id, m_ObjMan, GetSprite(new FactorySpriteInfo(SPRITE_TYPE_ID.NORMAL_SPRITE, typeInfo.TextureName, null)), ComponentTypeID.CID_RENDER_FIELD_ITEM);
            }
            else if (ItemID.ITEM_ID_FROG == fieldItemID)
            {
                fieldEntity = new CmpFieldFrog(id, m_ObjMan);

                List<ISprite> tempSpriteList = new List<ISprite>();
                tempSpriteList.Add(GetSprite(new FactorySpriteInfo(SPRITE_TYPE_ID.NORMAL_SPRITE, typeInfo.TextureName, null)));
                tempSpriteList.Add(GetSprite(new FactorySpriteInfo(SPRITE_TYPE_ID.ROTATE_SPRITE, null, fieldEntity)));

                render = new CmpDefaultRender(id, m_ObjMan, GetSprite(new FactorySpriteInfo(SPRITE_TYPE_ID.COMPOSITE_SPRITE, null, tempSpriteList)), ComponentTypeID.CID_RENDER_FIELD_ITEM);
                tempSpriteList.Clear();

            }

            m_ObjMan.AddComponent(fieldEntity);
            m_ObjMan.AddComponent(render);
            return fieldEntity;

        }

        private ICmpEntity GetScene()
        {
            GObjectID id = new GObjectID();
            ICmpScene scene1 = new CmpFieldScene(id, m_ObjMan);// , UpdateRayer.UPDATE_NONE);
            m_ObjMan.AddComponent(scene1);
            return scene1;
        }

        private ICmpEntity GetMalaria()
        {
            GObjectID id = new GObjectID();
            CmpMalaria malaria = new CmpMalaria(id, m_ObjMan);
            m_ObjMan.AddComponent(malaria);
            return malaria;
        }
        
        private ICmpEntity GetChildren()
        {
            GObjectID id = new GObjectID();

            CmpChildren character = new CmpChildren(id, m_ObjMan);
            m_ObjMan.AddComponent(character);
            return character;
        }

        private ICmpEntity GetClickAbleEntity(ObjectTypeInfo typeInfo)
        {
            GObjectID id = new GObjectID();

            ObjectTypeInfo tempType = new ObjectTypeInfo();
            tempType.extraInfo = typeInfo.extraInfo;
            ICmpItem cmpItem = (ICmpItem)GetItemEntity(tempType);

            CmpClickAblePanel clickPanel = new CmpClickAblePanel(id, m_ObjMan, typeInfo.TextureName, cmpItem);
             m_ObjMan.AddComponent(clickPanel);

            ICmpRender render = new CmpDefaultRender(id, m_ObjMan, GetSprite(new FactorySpriteInfo(SPRITE_TYPE_ID.CHANGESOURCE_SPRITE, typeInfo.TextureName, clickPanel)), ComponentTypeID.CID_RENDER_ITEMPANEL);//CreateRender(id, ComponentTypeID.CID_RENDER_ITEMPANEL, typeInfo.RenderID, typeInfo.TextureName, objMan, entity)
             m_ObjMan.AddComponent(render);

            return clickPanel;
        }

        private ICmpEntity GetCoolTimePanel(ObjectTypeInfo typeInfo)
        {
            GObjectID id = new GObjectID();

            ObjectTypeInfo tempType = new ObjectTypeInfo();
            tempType.extraInfo = typeInfo.extraInfo;
            ICmpItem cmpItem = (ICmpItem)GetItemEntity(tempType);

            CmpClickAblePanel clickPanel = new CmpClickAblePanel(id, m_ObjMan, typeInfo.TextureName, cmpItem);
            m_ObjMan.AddComponent(clickPanel);

            List<ISprite>  tempSpriteList = new List<ISprite>();
            tempSpriteList.Add(GetSprite(new FactorySpriteInfo(SPRITE_TYPE_ID.NORMAL_SPRITE, typeInfo.TextureName, null)));
            tempSpriteList.Add(GetSprite(new FactorySpriteInfo(SPRITE_TYPE_ID.RELATIVE_SPRITE, typeInfo.TextureName, clickPanel)));
            ICmpRender render = new CmpDefaultRender(id, m_ObjMan, GetSprite(new FactorySpriteInfo(SPRITE_TYPE_ID.COMPOSITE_SPRITE, null, tempSpriteList)), ComponentTypeID.CID_RENDER_ITEMPANEL);

            tempSpriteList.Clear();
            m_ObjMan.AddComponent(render);

            return clickPanel;
        }   

        private Object GetItemEntity(ObjectTypeInfo typeInfo)
        {
            ItemID itemID = (ItemID)typeInfo.extraInfo;
            ICmpItem itemEntity = null;
            GObjectID id = new GObjectID();
            ObjectManager objMan = m_ObjMan;

            if (ItemID.ITEM_ID_PILL == itemID)
            {
                itemEntity = new CmpPillItem(id, objMan);
            }

            else if (ItemID.ITEM_SHIELD == itemID)
            {
                itemEntity = new CmpShieldItem(id, objMan);
            }

            else if (ItemID.ATTACK_HAND == itemID)
            {
                itemEntity = new CmpHandAttack(id, objMan);
            }

            else if (ItemID.ATTACK_SLICE == itemID)
            {
                itemEntity = new CmpSliceAttack(id, objMan);
            }

            else if (ItemID.ITEM_ID_FLYPAPER == itemID)
            {
                itemEntity = new CmpFlyPaper(id, objMan);
            }

            else if (ItemID.ITEM_ID_FROG == itemID)
            {
                itemEntity = new CmpFrogItem(id, objMan);
            }

            else if (ItemID.ATTACK_MOVE == itemID)
            {
                itemEntity = new CmpMoveItem(id, objMan);
            }

            else if( ItemID.ITEM_WEB == itemID )
            {
                itemEntity = new CmpWebItem(id, objMan);
            }

            objMan.AddComponent(itemEntity);
            return itemEntity;
        }

     

        private ISprite GetSprite(FactorySpriteInfo spriteInfo)
        {
            return (ISprite)m_SpriteFactory.GetObject(spriteInfo);
        }

    }
}
